package testing_package;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.SocketChannel;
import java.util.Iterator;

public class selectorBlocking {

	/**
	 * @param args
	 */
	static int port = 4445;
	public static void main(String[] args) {
		// Create a selector and register two socket channels
		Selector selector = null;
		try {
		    // Create the selector
		    selector = Selector.open();

		    // Create two non-blocking sockets. This method is implemented in
		    // Creating a Non-Blocking Socket.
		    SocketChannel sChannel1 = createSocketChannel("localhost", port);
		    SocketChannel sChannel2 = createSocketChannel("localhost", port);

		    // Register the channel with selector, listening for all events
		    sChannel1.register(selector, sChannel1.validOps());
		    sChannel2.register(selector, sChannel2.validOps());
		    
		    
		    System.out.println(sChannel1.isOpen());
		    System.out.println(sChannel2.isOpen());
		    System.out.println(sChannel1.isConnected());
		    System.out.println(sChannel2.isConnected());
		    		    
		} catch (IOException e) {
		}

		// Wait for events
		while (true) {
		    try {
		        // Wait for an event
		    	System.out.println("Listening...");
		        selector.select();
		        System.out.println("Listened");
		    } catch (IOException e) {
		        // Handle error with selector
		        break;
		    }

		    // Get list of selection keys with pending events
		    Iterator it = selector.selectedKeys().iterator();

		    // Process each key at a time
		    while (it.hasNext()) {
		        // Get the selection key
		        SelectionKey selKey = (SelectionKey)it.next();

		        // Remove it from the list to indicate that it is being processed
		        it.remove();

		        try {
		            processSelectionKey(selKey);
		        } catch (IOException e) {
		            // Handle error with channel and unregister
		            selKey.cancel();
		        }
		    }
		}


	}
	
	public static void processSelectionKey(SelectionKey selKey) throws IOException {
	    // Since the ready operations are cumulative,
	    // need to check readiness for each operation
	    if (selKey.isValid() && selKey.isConnectable()) {
	        // Get channel with connection request
	        SocketChannel sChannel = (SocketChannel)selKey.channel();

	        boolean success = sChannel.finishConnect();
	        if (!success) {
	            // An error occurred; handle it

	            // Unregister the channel with this selector
	            selKey.cancel();
	        }
	    }
	    if (selKey.isValid() && selKey.isReadable()) {
	        // Get channel with bytes to read
	        SocketChannel sChannel = (SocketChannel)selKey.channel();

	        // See Reading from a SocketChannel
	    }
	    if (selKey.isValid() && selKey.isWritable()) {
	        // Get channel that's ready for more bytes
	        SocketChannel sChannel = (SocketChannel)selKey.channel();

	        // See Writing to a SocketChannel
	    }
	}
	
	public static SocketChannel createSocketChannel(String hostName, int port) throws IOException {
	    // Create a non-blocking socket channel
	    SocketChannel sChannel = SocketChannel.open();
	    sChannel.configureBlocking(false);

	    // Send a connection request to the server; this method is non-blocking
	    sChannel.connect(new InetSocketAddress(hostName, port));
	    return sChannel;
	}



}
